/***************************************************************************
 *   Copyright (C) 2005 by Christophe GONZALES and Pierre-Henri WUILLEMIN  *
 *   {prenom.nom}_at_lip6.fr                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

/** @file
 * @brief Common tools used by learning algorithms
 *
 * @author Maroua HAMMAMI and Malak HAMZEH
 *
 * This file provides common tools used by various learning algorithms.
 * */
#ifndef DOXYGEN_SHOULD_SKIP_THIS

namespace gum {

	   // ==============================================================================
	    /// basic constructor
	   // ==============================================================================

    	INLINE InstantiationBoxChild::InstantiationBoxChild (unsigned int nbrModalities) : InstantiationBox::InstantiationBox(),__count(nbrModalities,0)
    	{   
		 GUM_CONSTRUCTOR( InstantiationBoxChild );	
	} 

	    // ==============================================================================
	    /// destructor
	   // ==============================================================================

	INLINE InstantiationBoxChild::~InstantiationBoxChild ()
    	{
       		GUM_DESTRUCTOR(InstantiationBoxChild);	
    	}


	INLINE const std::vector<unsigned int>& InstantiationBoxChild::count() const //gets the vector of unsigned int : __count (Nijk)
    	{
		return __count;
     	}

  	INLINE void InstantiationBoxChild::resetCount() //resets the vector of unsigned int to zeros
   	{
		for (unsigned int i = 0; i < __count.size(); ++i)				
			__count[i]=0;
   	}

  	INLINE void InstantiationBoxChild::increment(int i) //increments the element i of the vector
   	{
		++__count[i];
   	}

	/*Default constructor*/
	INLINE InstantiationBoxParent::InstantiationBoxParent(unsigned int nbrModalities): InstantiationBox(),__dbCases(0),__children(nbrModalities,0){
	GUM_CONSTRUCTOR(InstantiationBoxParent);
	}


	/*Destructor*/ 
	INLINE InstantiationBoxParent::~InstantiationBoxParent() {	
	GUM_DESTRUCTOR(InstantiationBoxParent);
	for(unsigned int i=0; i<__children.size();++i)
		delete(__children[i]);
	if(__dbCases!=0){	
		for(unsigned int i=0; i<__dbCases->size();++i)			
				__dbCases->operator[](i).clear();
	__dbCases->clear();}
	delete(__dbCases);
	  }		

	// ==============================================================================
	/// finds the row's list of the database table for a current value.
	// ==============================================================================
	// if the currentval is not found throw an exception	
	INLINE const InstantiationBoxParent::ListCases & InstantiationBoxParent::dbCases(unsigned int currentval) const {
	        if (!__dbCases) {
			GUM_ERROR ( NotFound, "dbcases not found" );
		}
		else {
			return __dbCases->operator[](currentval);
		}    	
	}
	
	// ==============================================================================
	/// check if the Parent has a child or not.
	// ==============================================================================	
	INLINE bool InstantiationBoxParent::hasChild(unsigned int i) const {
		return __children[i]!=0;
	}
			
	// ==============================================================================
	///  adding a child to his parent.
	// ==============================================================================	
	INLINE void InstantiationBoxParent::addChild(unsigned int i, InstantiationBox& __child) {
		__children[i]=&__child;	
	}

	INLINE InstantiationBox* InstantiationBoxParent::child(unsigned int i) const {
		return __children[i];
		}

	// ==============================================================================
	///  Deleting the pointer of the node.
	// ==============================================================================
	INLINE void InstantiationBoxParent::eraseDBCases() {
		if (!__dbCases) 
			GUM_ERROR ( NotFound, "dbcases not found" );		
		for(unsigned int i=0; i<__dbCases->size();++i)			
				__dbCases->operator[](i).clear();
		__dbCases->clear();
		}

	// ==============================================================================
	///  adding the row's number of the database table in a list.
	// ==============================================================================
	INLINE void InstantiationBoxParent::addCases(unsigned int i, unsigned int db_cases) {		
		if(__dbCases==0)
		{//Vector instantiation if null
			__dbCases=new std::vector<InstantiationBoxParent::ListCases>(__children.size());		
		}
		__dbCases->operator[](i).pushBack(db_cases);
	}
	INLINE void InstantiationBoxParent::resizeParent(unsigned int sz)
	{
		__dbCases->resize(sz);
		__children.resize(sz);
	}
		
  } /* namespace gum */
#endif  // DOXYGEN_SHOULD_SKIP_THIS
